package TAProgram;

//example:  (+,a,b,t1)  等价于 t1 := a + b
//example:  (*,a,b,t2)  等价于 t2 := a*b
//example:  (-.t2,t1,t3) 等价于 t3 = t2-t1
public class TACode {
    OperatorType operator;//操作符
    Variable operandA;//操作数A
    Variable operandB;//操作数B
    Variable result;//结果值

    String codeSeq;
    TACode prev,next;
    Boolean active;

    public TACode(OperatorType operator, Variable operandA, Variable operandB, Variable result, TACode father) {
        this.operator = operator;
        this.operandA = operandA;
        this.operandB = operandB;
        this.result = result;
        this.prev = father;
        this.next = null;
        this.codeSeq = null;
        this.active = true;
    }

    public static void die(TACode taCode){
        taCode.setActive(false);
    }

    public void update(OperatorType operator, Variable operandA, Variable operandB, Variable result){
        this.operator = operator;
        this.operandA = operandA;
        this.operandB = operandB;
        this.result = result;
        this.active = true;
    }

    public TACode() {
    }

    public static TACode createTACode(OperatorType operator, Variable operandA, Variable operandB, Variable result, TACode father){
        TACode code = new TACode();
        code.setOperator(new OperatorType(operator));
        code.setOperandA(new Variable(operandA));
        code.setOperandB(new Variable(operandB));
        code.setResult(new Variable(result));
        code.setPrev(father);
        code.setNext(null);
        code.setActive(true);
        return code;
    }
    public static TACode createGoToCode(String name){
        TACode code = new TACode();
        code.codeSeq = name;
        code.setActive(true);
        return code;
    }

    public String getExpression(){
        String expression = "";
        if(this.getOperandA() != null && this.operandA.getName() != "") {
            expression += this.operandA.getName();
        }else{
            if(this.getOperandA() != null && this.operandA.getValueType() != null){
                if(this.getOperandA() != null && this.operandA.valueType.equals(ValueType.FLOAGTYPE)){
                    expression += this.operandA.getConstFloatValue().toString();
                }else if(this.operandA.valueType.equals(ValueType.INTTYPE)){
                    expression += this.operandA.getConstIntValue().toString();
                }else if(this.operandA.valueType.equals(ValueType.STRINGTYPE)){
                    expression += this.operandA.getConstStringValue();
                }
            }
        }

        if(this.getOperator() != null && this.getOperator().getName() != ""){
            expression += this.getOperator().getName();
        }

        if(this.getOperandB()!= null && this.operandB.getName() != "") {
            expression += this.operandB.getName();
        }else{
            if(this.getOperandB()!=null && this.operandB.valueType != null){
                if(this.operandB.valueType.equals(ValueType.FLOAGTYPE)){
                    expression += this.operandB.getConstFloatValue().toString();
                }else if(this.operandB.valueType.equals(ValueType.INTTYPE)){
                    expression += this.operandB.getConstIntValue().toString();
                }else if(this.operandB.valueType.equals(ValueType.STRINGTYPE)){
                    expression += this.operandB.getConstStringValue();
                }
            }
        }
        return expression;
    }

    @Override
    public String toString() {
        String code = "";
        if(!this.getActive()) return code;
        //是goto指令
        if(codeSeq != null){
            code += "GOTO " + codeSeq;
            return code;
        }
        if(result != null){
            code += result.toString();
            code += "=";
        }
        if(operandA != null){
            code += operandA.toString();
        }
        if(operator != null){
            code += operator.toString();
        }
        if(operandB != null){
            code += operandB.toString();
        }
        return code;
    }

    public OperatorType getOperator() {
        return operator;
    }

    public void setOperator(OperatorType operator) {
        this.operator = operator;
    }

    public Variable getOperandA() {
        return operandA;
    }

    public void setOperandA(Variable operandA) {
        this.operandA = operandA;
    }

    public Variable getOperandB() {
        return operandB;
    }

    public void setOperandB(Variable operandB) {
        this.operandB = operandB;
    }

    public Variable getResult() {
        return result;
    }

    public void setResult(Variable result) {
        this.result = result;
    }

    public TACode getPrev() {
        return prev;
    }

    public void setPrev(TACode prev) {
        this.prev = prev;
    }

    public TACode getNext() {
        return next;
    }

    public void setNext(TACode next) {
        this.next = next;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public String getCodeSeq() {
        if(this.codeSeq == null) return "";
        return codeSeq;
    }

    public void setCodeSeq(String codeSeq) {
        this.codeSeq = codeSeq;
    }
}
